package org.lzuploader.controller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.lzuploader.model.Localization;
import org.lzuploader.model.message.AbstractMessage;
import org.lzuploader.model.message.InfoMessage;
import org.lzuploader.model.result.Result;
import org.lzuploader.model.result.ResultCharacter;

/**
 * Parses an upload result.
 * @author Emmanuel Cron
 *
 */
public final class ResultParser
{
    /** The logger of this class. */
    private static Log log = LogFactory.getLog(ResultParser.class);
    
    /** Localization of this class. */
    private static Localization localization = Localization.getInstance();
    
    /** Last message produced by this class. */
    private static AbstractMessage lastMessage;
    
    /**
     * User should never instantiate this class.
     */
    private ResultParser()
    {
        throw new UnsupportedOperationException();
    }
    
    /**
     * Parses a string and returns a {@link Result} object.
     * @param toParse String to parse.
     * @return A {@link Result} object or <code>null</code> if string could not be parsed.
     */
    public static Result parse(final String toParse)
    {
        log.debug("Parsing new string into Result.");
        
        log.trace("Reseting last error message to none.");
        
        lastMessage = null;
        
        log.trace("Splitting string in lines.");
        
        final String[] lines = toParse.split("\n");
        
        if (lines.length < 1)
        {
            log.debug("String to parse does not contain any data, returning null.");
            lastMessage = new InfoMessage(
                localization.getString("DIALOG_TITLE_INFO"),
                localization.getString("DIALOG_EMPTY_UPLOAD_RESULTS")
            );
            
            return null;
        }
        
        log.trace("Creating Result object and processing each line.");
        
        final Result r = new Result();
        ResultCharacter rChar = null;
        
        for (String line : lines)
        {
            if (line.length() > 0)
            {
                if (line.startsWith("IT_DEL")) 
                {
                    try
                    {
                        r.setItemsDeleted(Integer.valueOf(line.substring(7)));
                    }
                    catch (final NumberFormatException nfe)
                    {
                        log.warn("NumberFormatException while reading IT_DEL: " + nfe.toString());
                    }
                }
                
                if (line.startsWith("IT_UPD")) 
                {
                    try
                    {
                        r.setItemsUpdated(Integer.valueOf(line.substring(7)));
                    }
                    catch (final NumberFormatException nfe)
                    {
                        log.warn("NumberFormatException while reading IT_UPD: " + nfe.toString());
                    }
                }
                
                if (line.startsWith("SP_DEL")) 
                {
                    try
                    {
                        r.setSpellsDeleted(Integer.valueOf(line.substring(7)));
                    }
                    catch (final NumberFormatException nfe)
                    {
                        log.warn("NumberFormatException while reading SP_DEL: " + nfe.toString());
                    }
                }
                
                if (line.startsWith("SP_UPD")) 
                {
                    try
                    {
                        r.setSpellsUpdated(Integer.valueOf(line.substring(7)));
                    }
                    catch (final NumberFormatException nfe)
                    {
                        log.warn("NumberFormatException while reading SP_UPD: " + nfe.toString());
                    }
                }
                
                if (line.startsWith("ST_UP_OK")) 
                {
                    r.setStatusUpdated(true);
                }
                
                if (line.startsWith("CH_NAME"))
                {
                    if (rChar != null)
                    {
                        r.getImportedCharacters().add(rChar);
                    }
                    
                    rChar = new ResultCharacter();
                    rChar.setName(line.substring(8));
                }
                
                if (line.startsWith("CH_INV_GUILD"))
                {
                    rChar.setStatusCode(ResultCharacter.INVALID_GUILD);
                }
                
                if (line.startsWith("CH_NOT_OWNED"))
                {
                    rChar.setStatusCode(ResultCharacter.NOT_OWNED);
                }
                
                if (line.startsWith("CH_UP_OK"))
                {
                    rChar.setCharacterUpdated(true);
                }
                
                if (line.startsWith("CH_PR_DL_OK"))
                {
                    rChar.setProfessionsDeleted(true);
                }
                
                if (line.startsWith("CH_CR_UP"))
                {
                    try
                    {
                        rChar.setCraftsUpdated(Integer.valueOf(line.substring(9)));
                    }
                    catch (final NumberFormatException nfe)
                    {
                        log.warn("NumberFormatException while reading CH_CR_UP: " + nfe.toString());
                    }
                }
                
                if (line.startsWith("CH_RG_UP"))
                {
                    try
                    {
                        rChar.setReagentsUpdated(Integer.valueOf(line.substring(9)));
                    }
                    catch (final NumberFormatException nfe)
                    {
                        log.warn("NumberFormatException while reading CH_RG_UP: " + nfe.toString());
                    }
                }
                
                if (line.startsWith("CH_DG_UP"))
                {
                    try
                    {
                        rChar.setDungeonsUpdated(Integer.valueOf(line.substring(9)));
                    }
                    catch (final NumberFormatException nfe)
                    {
                        log.warn("NumberFormatException while reading CH_DG_UP: " + nfe.toString());
                    }
                }
                
                if (line.startsWith("CH_SP_UP"))
                {
                    try
                    {
                        rChar.setCraftsSpecializationsUpdated(Integer.valueOf(line.substring(9)));
                    }
                    catch (final NumberFormatException nfe)
                    {
                        log.warn("NumberFormatException while reading CH_SP_UP: " + nfe.toString());
                    }
                }
            }
        }
        
        if (rChar != null)
        {
            r.getImportedCharacters().add(rChar);
        }
        
        return r;
    }
    
    /**
     * Returns wether this class generated a message on its last process or not.
     * @return <code>true</code> if last process generated an error, <code>false</code> otherwise.
     */
    public static boolean hasMessage()
    {
        return lastMessage != null;
    }
    
    /**
     * Returns the last message generated by this class.
     * @return A {@link AbstractMessage} object, or <code>null</code> if no error has been found.
     */
    public static AbstractMessage getLastMessage()
    {
        return lastMessage;
    }
}
